import styles from "./index.module.less";
import Icon from "@/components/Icon";
import { getComponentRootDom } from "../";
/**
 * 弹出消息 options
 * @param {String} content 消息内容
 * @param {String} type 消息类型  info  error  success  warn
 * @param {Number} duration 多久后消失
 * @param {HTMLElement} container 容器，消息会显示到该容器的正中；如果不传，则显示到页面正中
 * @param {Function} callBack 消息提示结束，回调函数
 */
export default (options = {}) => {
  const {
    content = "",
    type = "info",
    duration = 2000,
    container = document.body,
    callBack = null,
  } = options;

  //1.创建元素，添加样式
  const div = document.createElement("div");
  //因为要防止类名冲突所以开启了模块化-->因为模块化，所以最终类名带着哈希值-->因为带着哈希值所以确定提示类型不能只靠type，还需要获取哈希值
  div.className = `${styles["message"]} ${styles["message-" + type]}`;

  //2.添加内容
  //因为此时是源生js书写，并且需要一个vue提前写好的一个vue组件，那就需要获取该组件最终渲染完成的真实组件dom,并导出成html字符串
  div.innerHTML = `<span class="${styles.icon}">${
    getComponentRootDom(Icon, { type }).outerHTML
  }</span><div>${content}</div>`;

  //3.判断容器是否有定位配置，没有则相对定位
  //如果没有传入容器，那么此时消息是在body上的，但是如果body没有高，就会导致消息无法显示，所以这里判断此时没有传容器，那么就不给body加relative，让他自然继承居中整个窗口
  if (options.container) {
    if (getComputedStyle(container).position === "static") {
      container.style.position = "relative";
    }
  }

  //4.添加到容器上
  container.appendChild(div);

  //5.进行强行渲染，触发重绘（访问位置尺寸信息，浏览器会立即执行）
  div.clientHeight;

  //6.要做消息从下方向上出现，消失继续向上消失（前置条件是上一步强行渲染，导致浏览器先去应用当前dom样式配置，而不是执行完所有js才去执行渲染）
  //6-1 出现,从下往上出现
  div.style.opacity = 1;
  div.style.transform = "translate(-50%,-50%)";
  //6-2 消失,继续向上消失
  setTimeout(() => {
    div.style.opacity = 0;
    div.style.transform = "translate(-50%,-50%) translateY(-25px)";
    //添加过渡结束监听，等到过渡结束则删除消息元素
    div.addEventListener("transitionend", () => {
      div.remove();
      //提供消息结束，回调函数功能
      callBack && callBack();
    });
  }, duration);
};
